/**
  ******************************************************************************
  * @file    Libraries/Device/TS32Fx/TS32Fx_LL_Driver/inc/ts32fx_ll_timer.h
  * @author  TOPSYS Application Team
  * @version V1.0.0
  * @date    02-11-2018
  * @brief   This file contains all the TIMER LL firmware functions.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2018 TOPSYS</center></h2>
  *
  *
  *
  ******************************************************************************
  */ 
  
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TS32FX_LL_TIMER_H
#define __TS32FX_LL_TIMER_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "typedef.h"
#include "ts32fx.h"
     
/** @addtogroup TS32Fx_StdPeriph_Driver TS32Fx Driver
  * @{
  */
     
/** @addtogroup timer_interface_gr TIMER Driver
  * @ingroup  TS32Fx_StdPeriph_Driver
  * @{
  */ 

/** @addtogroup TIMER_LL_Driver TIMER LL Driver
  * @ingroup  timer_interface_gr
  * @brief Mainly the driver part of the TIMER module, which includes \b TIMER \b Register 
  * \b Constants, \b TIMER \b Exported \b Constants, \b TIMER \b Exported \b Struct, \b TIMER
  * \b Data \b transfers \b functions, \b TIMER \b Initialization \b and \b TIMER \b Configuration 
  * \b And \b Interrupt \b Handle \b function.
  * @{
  */
     
/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/
     
/** @defgroup TIMER_LL_Register_Constants TIMER LL Register Constants
  * @ingroup  TIMER_LL_Driver
  * @brief    TIMER LL register constant table definition
  *
  *
@verbatim   
  ===============================================================================
                                Register Constants
  ===============================================================================  
  
    Register Constants mainly encapsulates each bit in each group in the TIMER 
    register. In the process of configuration, the macro definition can be directly 
    called to configure the TIMER register, mainly for convenience. Understand the 
    configuration of the TIMER.
    
@endverbatim
  *
  * @{
  */

/***** TMRx_CON *****/
/*! RW, Capture selection
 */
#define LL_TIMER_CON_CAP_SEL(n)                      (((n)&0x3) << 16)
/*! RW, TIMERx counter pending, write 1 clear pending
 */
#define LL_TIMER_CON_CNT_PENDING                     (1UL << 15)
/*! RW, TIMERx capture pending, write 1 clear pending
 */
#define LL_TIMER_CON_CAP_PENDING                     (1UL << 14)
/*! TIMERx counter and capture pending mask
 */
#define LL_TIMER_CON_CNT_AND_CAP_PENDING_MASK        (0x3UL << 14)
/*! RW, TIMERx timer mode interrupt enable
 */
#define LL_TIMER_CON_CNT_IE                          (1UL << 13)
/*! RW, TIMERx capture mode interrupt enable
 */
#define LL_TIMER_CON_CAP_IE                          (1UL << 12)
/*! RW, TIMERx timer's prescaler setting
 */
#define LL_TIMER_CON_DIVISION_SET(n)                 (((n)&0x7) << 8)
/*! RW, TIMERx capture mode edge select
 */
#define LL_TIMER_CON_CAP_EDGE_SET(n)                 (((n)&0x3) << 6)
/*! RW, TIMERx mode select
 */
#define LL_TIMER_CON_MODE_SET(n)                     (((n)&0x3) << 4)
/*! TIMERRx mode select mask
 */
#define LL_TIMER_CON_MODE_MASK                       (0x3UL << 4)
/*! RW, TIMERx timer counter source select
 */
#define LL_TIMER_CON_SRC_SEL(n)                      (((n)&0x7) << 0)

/***** TMRx_CNT *****/
/*! RW, TIMERx Count register
 */
#define LL_TIMER_TMR16_CNT(n)                        (((n)&0xFFFF) << 0)
#define LL_TIMER_TMR32_CNT(n)                        (((n)&0xFFFFFFFF) << 0)
#define LL_IRTIMER_CNT(n)                            (((n)&0xFFFF) << 0)

/***** TMRx_PR *****/
/*! RW, TIMERx Prescaler register
 */
#define LL_TIMER_TMR16_PR(n)                         (((n)&0xFFFF) << 0)
#define LL_TIMER_TMR32_PR(n)                         (((n)&0xFFFFFFFF) << 0)
#define LL_IRTIMER_PR(n)                             (((n)&0xFFFF) << 0)
#define LL_IRTIMER_PR0(n)                            (((n)&0xFFFF) << 0)
#define LL_IRTIMER_PR1(n)                            (((n)&0xFFFF) << 0)

/***** TMRx_PWM *****/
/*! RW, TIMERx Pulse width modulation
 */
#define LL_TIMER_TMR16_PWM(n)                        (((n)&0xFFFF) << 0)
#define LL_TIMER_TMR32_PWM(n)                        (((n)&0xFFFFFFFF) << 0)
#define LL_IRTIMER_PWM(n)                            (((n)&0xFFFF) << 0)
#define LL_IRTIMER_PWM0(n)                           (((n)&0xFFFF) << 0)
#define LL_IRTIMER_PWM1(n)                           (((n)&0xFFFF) << 0)

/***** TMRx_BITCNT *****/
/*! RW, TIMERx Pulse width modulation
 */
#define LL_IRTIMER_BITCNT(n)                         (((n)&0xFF) << 0)

/***** TMRx_TXDAT *****/
/*! RW, TIMERx Pulse width modulation
 */
#define LL_IRTIMER_TXDAT(n)                          (((n)&0xFFFF) << 0)

/***** TMR IRSTA *****/
/*! RO, Write data mark, while bit is 1, write data is allowed
 */
#define LL_IRTIMER_IRSTA_WDATA_REQ                   (1UL << 10)
/*! RO, Send completion flag, write 1 clear pending
 */
#define LL_IRTIMER_IRSTA_TX_DONE_PENDING             (1UL << 9)
/*! RW, Error flag of Send buffer overflow, write 1 clear pending 
 */
#define LL_IRTIMER_IRSTA_BUF_FULL_ERR_PENDING        (1UL << 8)
/*! RW, Error flag of Send buffer overempty, write 1 clear pending 
 */
#define LL_IRTIMER_IRSTA_BUF_EMPTY_ERR_PENDING       (1UL << 7)
/*! RW, Error flag of Send buffer overempty, write 1 clear pending 
 */
#define LL_IRTIMER_IRSTA_ALL_PENDING_MASK            (0x7UL << 7)
/*! RO, buffer full mark 
 */
#define LL_IRTIMER_IRSTA_BUF_FULL                    (1UL << 6)
/*! RO, buffer empty mark 
 */
#define LL_IRTIMER_IRSTA_BUF_EMPTY                   (1UL << 5)
/*! RW, receive data empty interrupt enabled  
 */
#define LL_IRTIMER_IRSTA_BUF_EMPTY_IE                (1UL << 4)
/*! RW, Send complete interrupt enabled 
 */
#define LL_IRTIMER_IRSTA_TX_DONE_IE                  (1UL << 3)
/*! RW, Function of XOR is configuration 
 */
#define LL_IRTIMER_IRSTA_XOREN                       (1UL << 2)
/*! RW, PWM polarity selection 
 */
#define LL_IRTIMER_IRSTA_POLSEL                      (1UL << 1)
/*! RW, Infrared enabled 
 */
#define LL_IRTIMER_IRSTA_IR_EN                       (1UL << 0)

/**
  * @}
  */

/** @defgroup TIMER_LL_Exported_Constants TIMER LL Exported Constants
  * @ingroup  TIMER_LL_Driver
  * @brief    TIMER LL external constant definition
  *
@verbatim   
  ===============================================================================
                                Exported Constants
  ===============================================================================  
  
    Exported Constants mainly restricts the partial configuration of the abstraction 
    layer by using the form of enumeration to facilitate the use and understanding of 
    the module configuration. For the specific enumeration meaning, please refer to 
    the annotation of each module.

@endverbatim
  *
  * @{
  */
  
/***** DRIVER API *****/


/***** LL API *****/

/**
  * @brief Enumeration constant for low layer TIMER Prescaler for timer
  */
typedef enum {
    /*! Timer clock source 0 prescaler
     */
    LL_TIMER_PSC_NONE = 0,
    /*! Timer clock source 2 prescaler
     */
    LL_TIMER_PSC_2,
    /*! Timer clock source 4 prescaler
     */
    LL_TIMER_PSC_4,
    /*! Timer clock source 8 prescaler
     */
    LL_TIMER_PSC_8,
    /*! Timer clock source 16 prescaler
     */
    LL_TIMER_PSC_16,
    /*! Timer clock source 32 prescaler
     */
    LL_TIMER_PSC_32,
    /*! Timer clock source 64 prescaler
     */
    LL_TIMER_PSC_64,
    /*! Timer clock source 128 prescaler
     */
    LL_TIMER_PSC_128,
} TYPE_ENUM_LL_TIMER_PSC;

/**
  * @brief Enumeration constant for low layer TIMER Trigger mode selection in timer's capture mode
  */
typedef enum {
    /*! Timer trigger source selection: RISING
     */
    LL_TIMER_EDGE_SEL_RISING = 0,
    /*! Timer trigger source selection: FALLING
     */
    LL_TIMER_EDGE_SEL_FALLING,
    /*! Timer trigger source selection: RISING and FALLING
     */
    LL_TIMER_EDGE_SEL_RISING_FALLING,
} TYPE_ENUM_LL_TIMER_CAP_EDGE;

/**
  * @brief Enumeration constant for low layer TIMER clock source
  */
typedef enum {
    /*! Timer clock source selection: pin rising
     */
    LL_TIMER_SRC_INC_PIN_RISING = 0,
    /*! Timer clock source selection: pin falling
     */
    LL_TIMER_SRC_INC_PIN_FALLING,
    /*! Timer clock source selection: internal high rc half of clk rising and falling
     */
    LL_TIMER_SRC_INTERNAL_HIGH_SPEED_RC,
    /*! Timer clock source selection: half of 32K rising and falling
     */
    LL_TIMER_SRC_INTERNAL_32KHZ_RC,
    /*! Timer clock source selection: half of xosc rising and falling
     */
    LL_TIMER_SRC_EXTERNAL_CRYSTAL,
    /*! Timer clock source selection: the rising of sys clk
     */
    LL_TIMER_SRC_SYS_RISING,
} TYPE_ENUM_LL_TIMER_SRC_SEL;

  
/***** LL API AND DRIVER API *****/
/**
  * @brief Enumeration constant for low layer TIMER type of timer IO map
  */
typedef enum {
    /*! Select the pin of the timer io map none
     */
    LL_TIMER_IO_MAP_NONE = 0,
    /*! Select the pin of the timer io map0
     */
    LL_TIMER_IO_MAP0,
    /*! Select the pin of the timer io map1
     */
    LL_TIMER_IO_MAP1,
    /*! Select the pin of the timer io map0 and map1
     */
    LL_TIMER_IO_MAP_ALL,
} TYPE_ENUM_LL_TIMER_IO_MAP;

/**
  * @brief Enumeration constant for low layer TIMER the pattern of the timer
  */
typedef enum {
    /*! Timer mode selection: disable
     */
    LL_TIMER_MODE_SEL_DISABLE = 0,
    /*! Timer mode selection: counter mode
     */
    LL_TIMER_MODE_SEL_COUNTER,
    /*! Timer mode selection: PWM mode
     */
    LL_TIMER_MODE_SEL_PWM,
    /*! Timer mode selection: capture mode
     */
    LL_TIMER_MODE_SEL_CAPTURE,
}TYPE_ENUM_LL_TIMER_MODE_SEL;

/**
  * @}
  */

/** @defgroup TIMER_LL_Exported_Struct TIMER LL Exported Struct
  * @ingroup  TIMER_LL_Driver
  * @brief    TIMER LL external configuration structure definition
  *
@verbatim   
  ===============================================================================
                                Exported Struct
  ===============================================================================  

    Exported Struct mainly extracts the TIMER registers from the API, and abstracts 
    the structure. As long as it implements the low coupling between the registers 
    and the registers, the user only needs to configure the structure of the abstraction 
    layer and call hal_timer_init. Function, you can configure the TIMER module without 
    involving the configuration of the collective register.

@endverbatim
  *
  * @{
  */


/**
  * @brief Low layer TIMER Configure the timer structure
  */
typedef struct __ll_timer_init {
    /*! timer clock source selection
     */
    TYPE_ENUM_LL_TIMER_SRC_SEL     timer_src_sel;
    /*! prescaler value
     */
    TYPE_ENUM_LL_TIMER_PSC         prescaler;
} TYPE_LL_TIMER_INIT;

/**
  * @brief Low layer TIMER count mode Configure the timer structure
  */
typedef struct __ll_timer_cnt_cfg { 
    /*! count cycle value
     */
    u32                          count_period;
    /*! the initial value of count
     */
    u32                          count_initial;
    /*! count interrupt enalbe*/
    FunctionalState              count_ie;
} TYPE_LL_TIMER_CNT_CFG;

/**
  * @brief Low layer TIMER capture mode Configure the timer structure
  */
typedef struct __ll_timer_capture_cfg { 
    /*! trigger source selection
     */
    TYPE_ENUM_LL_TIMER_CAP_EDGE    capture_edge_sel;
    /* capture interrupt enable */
    FunctionalState                capture_ie;
} TYPE_LL_TIMER_CAP_CFG;

/**
  * @brief Low layer TIMER capture mode Configure the timer structure
  */
typedef struct __ll_timer_pwm_cfg { 
    /*! pwm cycle count value
     */
    u32                          pwm_period;
    /*! pwm high voltage count value
     */
    u32                          pwm_duty;
} TYPE_LL_TIMER_PWM_CFG;

/**
  * @brief Low layer TIMER Configure the timer structure
  */
typedef struct __ll_ir_tx_cfg{
    /*! carrier frequence
     */
    u16                          carrier_freq;
    /*! Set the cycle time of infrared transmission 1
     */    
    u16                          bit_1_period_cnt;
    /*! Set the carrier duration of infrared transmission 1
     */    
    u16                          bit_1_carrier_cnt;
    /*! Set the cycle time of infrared transmission 0
     */    
    u16                          bit_0_period_cnt;
    /*! Set the carrier duration of infrared transmission 0
     */    
    u16                          bit_0_carrier_cnt;
    /*! xor_en is used to which contrling RC5 to send ( 0:CW + Signal or 1:signal + CW )
     */
    FunctionalState              xor_en;
    /*! p_pol_en is used to which contrling PWM polarity
     */
    FunctionalState              p_pol_en;
} TYPE_LL_IR_TX_CFG;

/**
  * @brief Low layer TIMER Configure the timer structure
  */
typedef struct __ll_ir_frame_cfg{
    /*! bit period count
     */
    u16                          start_bit_period_cnt;
    /*! bit carrier count
     */
    u16                          start_bit_carrier_cnt;
    /*! Infrared data buffer, send frist bit whitch is the high bit
     */
    u16                          *ir_buf;
    /*! Infrared frame data bit count ( without start bit )
     */
    u8                           frame_bit_cnt;
} TYPE_LL_IR_FRAME_CFG;


/**
  * @}
  */

/** @defgroup TIMER_LL_Interrupt TIMER LL Interrupt Handle function
  * @brief   TIMER LL Interrupt Handle function
  *
@verbatim   
  ===============================================================================
                        Interrupt Handle function
  ===============================================================================  

    This subsection provides a set of functions allowing to manage the TIMER  
    Interrupt Handle function.

    how to use?

    The TIMER interrupt handler uses a callback method that reserves the interface 
    to the user in the form of a callback function. The client needs to initialize 
    the callback function when initializing the TIMER in order for the interrupt to 
    be processed normally. 
   
@endverbatim
  *
  * @{
  */



/**
  * @}
  */
  
/** @defgroup TIMER_LL_Inti_Cfg TIMER LL Initialization And Configuration
  * @brief    TIMER LL Initialization And Configuration
  *
@verbatim   
  ===============================================================================
                        Initialization And Configuration
  ===============================================================================  

    This subsection provides a set of functions allowing to manage the TIMER data 
    Initialization and Configuration.
    
    how to use?

@endverbatim
  *
  * @{
  */
  
/**
  * @brief  Low layer timer init function
  * @param  p_timer: Set to division and source colock of TIMERx
  * @param  p_init : Configure the p_timer initialization structure
  * @retval None
  */
void ll_timer_init(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_INIT *p_init);

/**
  * @brief  Low layer timer delete init function
  * @param  p_timer: Structure pointer set to TIMER or TIMER1
  * @retval None
  */
void ll_timer_deinit(TIMER_TypeDef *p_timer);
  
/**
  * @brief  Low layer timer disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_stop(TIMER_TypeDef *p_timer);

/**
  * @brief  Low layer timer start function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_start(TIMER_TypeDef *p_timer, TYPE_ENUM_LL_TIMER_MODE_SEL mode_sel);

/**
  * @brief  Low layer timer0~timer4 cnt set
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  cnt_set  : timer0~timer4 cnt value(timer0~timer3 16bits cnt value, timer4 32bits cnt value)
  * @retval None
  */
void ll_timer_cnt_set(TIMER_TypeDef *p_timer, u32 cnt_set);

/**
  * @brief  Low layer timer cnt get
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval timer cnt value(timer0~timer3 16bits cnt value, timer4 32bits cnt value)
  */
u32 ll_timer_cnt_get(TIMER_TypeDef *p_timer);

/**
  * @brief  set timer to count mode
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  cnt_cfg  : Structure pointer set to TIMERx counter mode
  * @retval None
  */
void ll_timer_cnt_mode_config(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_CNT_CFG *cnt_cfg);

/**
  * @brief  set timer to pwm mode
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  pwm_cfg  : Structure pointer set to TIMERx pwm mode
  * @retval None
  */
void ll_timer_pwm_mode_config(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_PWM_CFG *pwm_cfg);

/**
  * @brief  set timer to capture mode
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  cap_cfg  : Structure pointer set to TIMERx capture mode
  * @retval None
  */
void ll_timer_cap_mode_config(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_CAP_CFG *cap_cfg);

/**
  * @brief  Infrared timer initialization 
  * @param  p_timer  : Structure pointer set to TIMER5
  * @param  p_init : Configure the p_timer initialization structure
  * @retval None
  */
void ll_irtimer_init(TIMER5_TypeDef *p_timer, TYPE_LL_TIMER_INIT *p_init);

/**
  * @brief  Low layer timer disable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_stop(TIMER5_TypeDef *p_timer);

/**
  * @brief  Low layer timer start function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_start(TIMER5_TypeDef *p_timer, TYPE_ENUM_LL_TIMER_MODE_SEL mode_sel);

/**
  * @brief  Low layer timer5 cnt set
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  cnt_set  : timer5 cnt value(timer5 16bits cnt value)
  * @retval None
  */
void ll_irtimer_cnt_set(TIMER5_TypeDef *p_timer, u32 cnt_set);

/**
  * @brief  Low layer timer5 cnt get
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval timer5 cnt value(timer5 16bits cnt value)
  */
u32 ll_irtimer_cnt_get(TIMER5_TypeDef *p_timer);

/**
  * @brief  set timer to count mode
  * @param  p_timer  : Structure pointer set to TIMER5
  * @param  cnt_cfg  : Structure pointer set to TIMERx counter mode
  * @retval None
  */
void ll_irtimer_cnt_mode_config(TIMER5_TypeDef *p_timer, TYPE_LL_TIMER_CNT_CFG *cnt_cfg);

/**
  * @brief  Set timer to pwm mode
  * @param  p_timer  : Structure pointer set to TIMER5
  * @param  pwm_cfg  : Structure pointer set to TIMERx pwm mode
  * @retval None
  */
void ll_irtimer_pwm_mode_config(TIMER5_TypeDef *p_timer, TYPE_LL_TIMER_PWM_CFG *pwm_cfg);

/**
  * @brief  Set timer to capture mode 
  * @param  p_timer  : Structure pointer set to TIMER5
  * @param  cap_cfg  : Structure pointer set to TIMERx capture mode
  * @retval None
  */
void ll_irtimer_cap_mode_config(TIMER5_TypeDef *p_timer, TYPE_LL_TIMER_CAP_CFG *cap_cfg);

/**
  * @brief  Infrared send initialization
  * @param  p_timer       : Structure pointer set to TIMER5
  * @param  ir_tx_cfg     : Structure pointer set to TIMER5 infrared send configure
  * @retval None
  */
void ll_ir_tx_init(TIMER5_TypeDef *p_timer, TYPE_LL_IR_TX_CFG *ir_tx_cfg);

/**
  * @brief  Send infrared data
  * @param  p_timer     : Structure pointer set to TIMER5
  * @param  p_ir_frame  : Structure pointer set to Infrared structure
  * @retval None
  */
void ll_ir_tx(TIMER5_TypeDef *p_timer, TYPE_LL_IR_FRAME_CFG *p_ir_frame);

/**
  * @brief  Send infrared data( using interrupt mode )
  * @param  p_timer     : Structure pointer set to TIMER5
  * @param  p_ir_frame  : Structure pointer set to Infrared structure
  * @retval None
  */
void ll_ir_int_tx(TIMER5_TypeDef *p_timer, TYPE_LL_IR_FRAME_CFG *p_ir_frame);

/**
  * @}
  */
  
/** @defgroup TIMER_LL_Data_Transfers TIMER LL Data transfers functions
  * @brief    TIMER LL Data transfers functions 
  *
@verbatim   
  ===============================================================================
                            Data transfers functions
  ===============================================================================  

    This subsection provides a set of functions allowing to manage the TIMER data 
    transfers and receive.
  
@endverbatim
  *
  * @{
  */
  
/**
  * @brief  Low layer timer counter interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval None
  */
void ll_timer_cnt_interrupt_enable(TIMER_TypeDef *p_timer);
/**
  * @brief  Low layer timer counter interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval None
  */
void ll_timer_cnt_interrrupt_disable(TIMER_TypeDef *p_timer);
/**
  * @brief  Low layer timer counter interrupt get enable or disable function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval result
  */
#define LL_TIMER_CNT_INTERRUPT_GET(p_timer)                    ((p_timer)->TMR_CON & LL_TIMER_CON_CNT_IE)

/**
  * @brief  Low layer timer capture interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval None
  */
void ll_timer_cap_interrupt_enable(TIMER_TypeDef *p_timer);
/**
  * @brief  Low layer timer capture interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval None
  */
void ll_timer_cap_interrupt_disable(TIMER_TypeDef *p_timer);
/**
  * @brief  Low layer timer cap interrupt get enable or disable function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval result
  */
#define LL_TIMER_CAP_INTERRUPT_GET(p_timer)                    ((p_timer)->TMR_CON & LL_TIMER_CON_CAP_IE)

/**
  * @brief  Low layer Infrared transmission data buf empty interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_buf_empty_interrupt_enable(TIMER5_TypeDef *p_timer);
/**
  * @brief  Low layer Infrared transmission data buf empty interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_buf_empty_interrupt_disable(TIMER5_TypeDef *p_timer);
/**
  * @brief  Low layer Infrared transmission data buf empty interrupt get enable or disable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval result
  */
#define LL_IRTIMER_BUF_EMPTY_INTERRUPT_GET(p_timer)            ((p_timer)->TMR_IRSTA & LL_IRTIMER_IRSTA_BUF_EMPTY_IE)

/**
  * @brief  Low layer infrared transmission done interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_tx_done_interrupt_enable(TIMER5_TypeDef *p_timer);
/**
  * @brief  Low layer infrared transmission done interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_tx_done_interrupt_disable(TIMER5_TypeDef *p_timer);
/**
  * @brief  Low layer infrared transmission done interrupt get enable or disable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval result
  */
#define LL_IRTIMER_TX_DONE_INTERRUPT_GET(p_timer)              ((p_timer)->TMR_IRSTA & LL_IRTIMER_IRSTA_TX_DONE_IE)


/**
  * @brief  Low layer infrared enabled function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_ir_enable(TIMER5_TypeDef *p_timer);

/**
  * @brief  Low layer infrared disable function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
void ll_irtimer_ir_disable(TIMER5_TypeDef *p_timer);

/**
  * @brief  calculate timer timeout to count period (Timer1-Timer3  advice 1ms(when use system pll && timer clock is system clock )
  * @param  p_timer  :      Structure pointer set to TIMERx
  * @param  src_sel  :      Timer clock source selection
  * @param  psc             Structure pointer set to TIMERx counter mode
  * @param  source_ms_data  
  * @note   This function can only be used for timers using the system clock (internal clock and PLL).    
  *         Timer1-Timer3  advice 1ms(psc = LL_TIMER_PSC_4),   2-10ms(psc=LL_TIMER_PSC_16),  11-30ms(psc=LL_TIMER_PSC_32), 30-70ms(psc=LL_TIMER_PSC_64)   71-100ms(psc=LL_TIMER_PSC_128)    
  *         Timer4         advice 1ms-1s(psc = LL_TIMER_PSC_4)   
  *         advise to use psc=LL_TIMER_PSC_4   
  * @retval None  
  */
u32 ll_timer_ms_cal(TIMER_TypeDef *p_timer,TYPE_ENUM_LL_TIMER_SRC_SEL src_sel, TYPE_ENUM_LL_TIMER_PSC psc, u16 delay_ms_data);

/**
  * @brief  calculate timer pwm
  * @param  p_timer  :      Structure pointer set to TIMERx
  * @param  freq_hz  :      freq(hz) value from 10Hz----1MHz 
  * @param  duty_per :      duty percentage from 1---100
  * @note   duty_time==timer_count * prescaler / timer_src_sel
  *         freq   = timer_src_sel /(timer_count * prescaler)
  *         timer_count = (timer_src_sel /freq )/prescaler
  * @retval None  
  */
void ll_timer_pwm_init(TIMER_TypeDef *p_timer, u32 freq_hz, u8 duty_per);

/**
  * @brief  timer count initialization (Timer0-Timer3  advice timing time <1ms; Timer4 advice timing timer <10s
  * @param  p_timer  :      Structure pointer set to TIMERx
  * @param  timing_ms:      Timer timing ms
  * @param  irq_sta  :      Count Interrupt enable or disable
  * @note   This function help user to initial timing time.      
  * @retval None  
  */
void ll_timer_count_init(TIMER_TypeDef *p_timer, u32 timing_ms, FunctionalState irq_sta);


/**
  * @brief  Low layer infrared enable get
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval result
  */
#define LL_IRTIMER_IR_EN_GET(p_timer)                          (p_timer->TMR_IRSTA & LL_IRTIMER_IRSTA_IR_EN)


/**
  * @brief  Low layer timer get counter interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval result
  */
#define LL_TIMER_CNT_PENDING_GET(p_timer)                      ((p_timer)->TMR_CON & LL_TIMER_CON_CNT_PENDING)

/**
  * @brief  Low layer timer clear counter interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval None
  */
#define LL_TIMER_CNT_PENDING_CLR(p_timer)                      ((p_timer)->TMR_CON = (p_timer)->TMR_CON & (~LL_TIMER_CON_CNT_AND_CAP_PENDING_MASK) | LL_TIMER_CON_CNT_PENDING)

/**
  * @brief  Low layer timer get capture interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval None
  */
#define LL_TIMER_CAP_PENDING_GET(p_timer)                      ((p_timer)->TMR_CON & LL_TIMER_CON_CAP_PENDING)

/**
  * @brief  Low layer timer clear capture interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER0 ~ TIMER5
  * @retval None
  */
#define LL_TIMER_CAP_PENDING_CLR(p_timer)                      ((p_timer)->TMR_CON = (p_timer)->TMR_CON & (~LL_TIMER_CON_CNT_AND_CAP_PENDING_MASK) | LL_TIMER_CON_CAP_PENDING)

/**
  * @brief  Low layer timer clear infrared tx done interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
#define LL_IRTIMER_TX_DONE_PENDING_GET(p_timer)                ((p_timer)->TMR_IRSTA & LL_IRTIMER_IRSTA_TX_DONE_PENDING)

/**
  * @brief  Low layer timer clear infrared tx done interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
#define LL_IRTIMER_TX_DONE_PENDING_CLR(p_timer)                ((p_timer)->TMR_IRSTA = (p_timer)->TMR_IRSTA & (~LL_IRTIMER_IRSTA_ALL_PENDING_MASK) | LL_IRTIMER_IRSTA_TX_DONE_PENDING)

/**
  * @brief  Low layer timer get buffer full error interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
#define LL_IRTIMER_BUF_FULL_ERR_PENDING_GET(p_timer)           ((p_timer)->TMR_IRSTA & LL_IRTIMER_IRSTA_BUF_FULL_ERR_PENDING)

/**
  * @brief  Low layer timer clear buffer full error interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
#define LL_IRTIMER_BUF_FULL_ERR_PENDING_CLR(p_timer)           ((p_timer)->TMR_IRSTA = (p_timer)->TMR_IRSTA & (~LL_IRTIMER_IRSTA_ALL_PENDING_MASK) | LL_IRTIMER_IRSTA_BUF_FULL_ERR_PENDING)

/**
  * @brief  Low layer timer get buffer empty error interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
#define LL_IRTIMER_BUF_EMPTY_ERR_PENDING_GET(p_timer)          ((p_timer)->TMR_IRSTA & LL_IRTIMER_IRSTA_BUF_EMPTY_ERR_PENDING)

/**
  * @brief  Low layer timer clear buffer empty error interrupt pending function
  * @param  p_timer  : Structure pointer set to TIMER5
  * @retval None
  */
#define LL_IRTIMER_BUF_EMPTY_ERR_PENDING_CLR(p_timer)          ((p_timer)->TMR_IRSTA = (p_timer)->TMR_IRSTA & (~LL_IRTIMER_IRSTA_ALL_PENDING_MASK) | LL_IRTIMER_IRSTA_BUF_EMPTY_ERR_PENDING)



/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

/**
  * @}
  */

/**
  * @}
  */

#endif //__TS32FX_LL_TIMER_H

/*************************** (C) COPYRIGHT 2018 TOPSYS ***** END OF FILE *****/
